package com.spark.actions;

import java.io.PrintWriter;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.regex.Pattern;

import javax.servlet.http.HttpServletResponse;

import org.apache.ibatis.session.SqlSession;

import com.spark.actions.sys.CompanyAction;
import com.spark.core.JacksonMapper;
import com.spark.core.Message;
import com.spark.core.SparkContext;
import com.spark.core.XMap;
import com.spark.util.MemcachedHelper;

@SuppressWarnings("unchecked")
public class BaseAction {
	
	public static final int DEFAULT_QUERY_MAX_PAGE_SIZE = 100;
	public static final int DEFAULT_QUERY_PAGE_SIZE = 10;
	public static final int DEFAULT_QUERY_PAGE_NUM = 1;
	
	public static final String DEFAULT_ORDER_TYPE_DESC  = "DESC";
	public static final String DEFAULT_ORDER_TYPE_ASC = "ASC";
	
	public static final String QUERY_PAGE_SIZE = "_ps";
	public static final String QUERY_PAGE_NUM = "_pn";
	public static final String PARAMETER = "parameter";
	public static final String LIMITS_OFFSET = "OFFSET";
	public static final String LIMITS_LENGTH = "LENGTH";
	public static final String STATMENT_COUNT = "Count";
	public static final String ORDER_SQL = "ORDER_SQL";
	public static final String ORDER_FIELD = "ORDER_FIELD";
	public static final String ORDER_TYPE = "ORDER_TYPE";
	public static final String TOTAL = "total";
	public static final String LIST = "list";
	
	public static final String FIELD_PERIOD_YEAR = "PERIOD_YEAR";
	public static final String FIELD_PERIOD_NUM = "PERIOD_NUM";	
	public static final String FIELD_CREATED_BY_NAME = "CREATED_BY_NAME";
	public static final String FIELD_CREATED_BY = "CREATED_BY";
	public static final String FIELD_CREATION_DATE = "CREATION_DATE";
	public static final String FIELD_LAST_UPDATED_BY = "LAST_UPDATED_BY";
	public static final String FIELD_LAST_UPDATE_DATE = "LAST_UPDATE_DATE";
	
	public static final String ACTION_QUERY = "query";
	public static final String ACTION_INSERT = "insert";
	public static final String ACTION_DELETE = "delete";
	public static final String ACTION_UPDATE = "update";
	public static final String ACTION_EXECUTE = "execute";
	
	public static void parsePageSizeAndPageNum(SparkContext context,Map para){
		XMap request = context.getParameter();
		Integer pageSize = Math.min(request.getInt(QUERY_PAGE_SIZE,DEFAULT_QUERY_PAGE_SIZE),DEFAULT_QUERY_MAX_PAGE_SIZE);
		Integer pageNum = request.getInt(QUERY_PAGE_NUM,DEFAULT_QUERY_PAGE_NUM);
		para.put(LIMITS_OFFSET, (pageNum-1)*pageSize);
		para.put(LIMITS_LENGTH, pageSize);
	}
	
	protected String getOrderField(Map para){
		return (String)para.get(ORDER_FIELD);
	}
	
	protected String getOrderType(Map para, String defaultType){
		String ot = (String)para.get(ORDER_TYPE);
		return ot == null ? defaultType : ot;
	}
	
	
	protected void selectCount(SqlSession sqlSession,String statement,Map param,Message message){	
		Integer pageSize = (Integer)param.get(BaseAction.LIMITS_LENGTH);
		if (pageSize!=-1) {
			Integer total = (Integer) sqlSession.selectOne(statement.concat(STATMENT_COUNT), param);
			message.put(TOTAL, total);
		}
	}
	
	protected Integer getCompanyId(SparkContext context){
		return (Integer)context.getSession().get(SparkContext.FIELD_COMPANY_ID);
	}
	
	protected Integer getAccountSetId(SparkContext context){
		return (Integer)context.getSession().get(SparkContext.FIELD_ACCOUNT_SET_ID);
	}
	
	
	protected String getUserName(SparkContext context){
		String suk = context.getRequest().getParameter(SparkContext.SPARK_USER_KEY);
		if(suk != null){
			String value = (String)MemcachedHelper.get(suk);
			if(value != null) {
				String[] arr = value.split("#");
				if (arr.length == 4) {
					return arr[3];
				}
			}
		}
		return null;
	}
	
	//TODO:测试写死的
	protected Integer getPeriodYear(SparkContext context){
		return Calendar.getInstance().get(Calendar.YEAR);
	}
	//TODO:测试写死的
	protected Integer getPeriodNum(SparkContext context){
		return Calendar.getInstance().get(Calendar.MONTH) + 1;
	}
	
	protected Integer getUserId(SparkContext context){
		return (Integer)context.getSession().get(SparkContext.FIELD_USER_ID);
	}
	protected void setCompanyId(Map map,SparkContext context){
		map.put(CompanyAction.FIELD_COMPANY_ID, getCompanyId(context));
	}
	
	protected void setAccountSetId(Map map,SparkContext context){
		map.put(SparkContext.FIELD_ACCOUNT_SET_ID, getAccountSetId(context));
	}
	
	protected void setUserId(Map map,SparkContext context){
		map.put(SparkContext.FIELD_USER_ID, getUserId(context));
	}
	
	
	protected void createWho(Map map,SparkContext context){
		map.put(FIELD_CREATED_BY, getUserId(context));
		map.put(FIELD_CREATED_BY_NAME, getUserName(context));
		map.put(FIELD_CREATION_DATE, new Date());
		map.put(FIELD_LAST_UPDATED_BY, getUserId(context));
		map.put(FIELD_LAST_UPDATE_DATE, new Date());
	}
	
	
	protected void updateWho(Map map,SparkContext context){
		map.put(FIELD_LAST_UPDATED_BY, getUserId(context));
		map.put(FIELD_LAST_UPDATE_DATE, new Date());
	}

	
	public Map getRequestData(SparkContext context) {
		Map map = (Map) context.getParameter();
		return (Map) map.get(SparkContext.REQUEST_DATA);
	}
	
	
	
	public Map getFormData(SparkContext context){
		Map requestData = getRequestData(context);
		if(requestData == null) return null;
		List list = (List)requestData.get(PARAMETER);
		Map map = null;
		if(list!=null && list.size() > 0){
			map = (Map)list.get(0);
		}
		return map;
	}

	
	protected void setDefault(Map map, String key, Object defaultValue) {
		Object v = (Object) map.get(key);
		if (v == null) {
			map.put(key, defaultValue);
		}
	}

	public void writeMessage(SparkContext context, Message message) throws Exception {
		HttpServletResponse response = context.getResponse();
		PrintWriter out = null;
		try {
			out = response.getWriter();
			JacksonMapper.getInstance().writeValue(out, message);
		} finally {
			if (out != null) out.close();
		}
	}

	
	protected void doAction(SqlSession session, String action, String statement, Map map) {
		if (ACTION_INSERT.equals(action)) {
			session.insert(statement, map);
		} else if (ACTION_DELETE.equals(action)) {
			session.delete(statement, map);
		} else if (ACTION_UPDATE.equals(action)) {
			session.update(statement, map);
		}
	}
	
//	/**
//	 * 过滤掉null
//	 * @param map
//	 */
//	protected void filterNull(Map map){
//		Set set = map.keySet();
//		if (set != null) {
//			Iterator it = set.iterator();
//			while(it.hasNext()){
//				String key = (String)it.next();
//				if(map.get(key) == null) it.remove();
//			}
//		}
//	}
	
	/**
	 * 判断value不能为null和空,用作新增判断
	 * @param value
	 * @param message
	 * @param msg
	 * @return
	 */
	protected boolean isNotNull(Object value, Message message, String msg){
		if (value == null || "".equals(value.toString().trim())) {
			message.setInfo(msg);
			return false;
		}
		return true;
	}
	
	protected boolean isNotNullAndRestrict(Object value, Pattern p, Message message, String msg){
		boolean isValid = isNotNull(value,message,msg) ? p.matcher(value.toString()).matches() : false;
		if(!isValid) {
			message.setInfo(msg);
		}
		return isValid;
	}
	
	/**
	 * 判断是否为空，用作更新判断
	 * @param value
	 * @param message
	 * @param msg
	 * @return
	 */
	protected boolean isNotEmpty(Object value, Message message, String msg) {
		if (value!= null && "".equals(value.toString().trim())) {
			message.setInfo(msg);
			return false;
		}
		return true;
	}
	
	/**
	 * 如果为null或者不为null符合正则返回true,否则返回false
	 * 
	 * @param value
	 * @param p
	 * @param message
	 * @param msg
	 * @return
	 */
	protected boolean isNullOrRestrict(Object value, Pattern p, Message message, String msg){
		if(value == null) {
			return true;
		} else if(!p.matcher(value.toString()).matches()) {
			message.setInfo(msg);
			return false;
		}
		return true;
	}
	
	protected Double transferDouble(Object value){
		if(value instanceof Integer){
			Integer v = (Integer)value;
			return Double.parseDouble(v.toString());
		}else if(value instanceof Double){
			return (Double)value;
		}
		return null;
	}
	
	protected String padding(String str, int length){
		String rt = str;
		int len = str.length();
		for(int i=len;i<length;i++){
			rt = "0"+rt;
		}
		return rt;
	}
	
	
	protected int getInt(Object o){
		return o == null ? 0 : ((Integer)o).intValue();
	}
	
	protected float getFloat(Object o){
		return o == null ? 0 : ((Float)o).floatValue();
	}

}
